"""
@name : 2021-07-28-迭代器与生成器
@author : wenyao
@projectname: xsfh
"""
#打印30以内能被3整除的数，放到一个列表里面
# print(list(filter(lambda x:x % 3 == 0,range(1,31))))

#列表推导式
# for i in range(1,31)  --> if --> return i
# print([i for i in range(1,31) if i%3==0])

#30以内能被3整除的数的平方
#return i**2
# print([i**2 for i in range(1,31) if i%3==0])

# 推导式嵌套
# names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva', 'Elven']]
# print([ name for lst in names for name in lst if name.count("e")>=2])

# li = []
# for lst in names:
#     for name in lst:
#         if name.count("e")>=2:
#             li.append(name)

#打印100以内能被3整除的数， 如果这个数是一个偶数，就取0，如果是奇数就取这个数
# print([i if i%2 else 0  for i in range(1,101) if not i%3])

#短路运算
# print( 2 and 3)
# i.isdigit() == True

# print([i if i%2==1 else 0  for i in range(1,101) if i%3==0])

#集合推导式   --> 去重
# str1 = "sdofiefawpf934u8tkvnsewr"
# print(set(str1))
# print({ i for i in str1})

#字典推导式
# str1="2rsf555gggbbcc"
# dict1 = {"a":1,"b":2}
# print({i:str1.count(i)  for i in str1})
# print({y:x for x,y in dict1.items()})

#过滤掉长度小于3的字符串列表，并将剩下的转换成大写字母
# q1 = ['a','ab','abc','abcd','abcde']
# print([i.upper() for i in q1 if len(i) >=3 ])

#求(x,y)其中x是0-5之间的偶数，y是0-5之间的奇数组成的元组列表
# print([(i,j) for i in range(6) if i%2 == 0 for j in range(6) if j%2 !=0])
#
# q3 = {'a': 10,'b': 34}
# print({y:x for x,y in q3.items()})
#
# q4 = {'B':3,'a':1,'b':6,'c':3,'A':4}
# # q4.get("b")
# # q4["b"]
# print({i.lower():q4.get(i.lower(),0)+q4.get(i.upper(),0) for i in q4})

# str1 = "weo9450fgjvw249fdsfkf309"
# tmp_dict = {}
# for i in str1:
#     tmp_dict[i] = tmp_dict.get(i,0) +1
    # if i in tmp_dict:
    #     tmp_dict[i] +=1
    # else:
    #     tmp_dict[i] =1

#####################可迭代对象###################
#实现了__iter__方法，并且该方法返回一个迭代器 这样子的对象就是一个可迭代对象
# >>> a = [1,2,3]
# >>> dir(a)
# ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
# >>> from collections import Iterable
#
# Warning (from warnings module):
#   File "__main__", line 1
# DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
# >>> isinstance(a, Iterable)
# True
# >>> isinstance(1, int)
# True
# >>>

#可迭代对象有哪些
#容器类型都是可迭代对象
#range
#打开的文件，socket

#凡是有__iter__并且这个方法返回一个迭代器的对象都称之为可迭代对象

####################迭代器#################
# 1、任何实现了__iter__()和__next__()都是迭代器
#__iter__()  返回自身
#__next__()  返回下一个值
#如果容器中没有更过元素了，则抛出StopIteration
#在for循环中，如果遇到了StopIteration时，就退出循环
# >>> a
# [1, 2, 3]
# >>> a.__iter__()
# <list_iterator object at 0x02E9AA50>
# >>> iter(a)
# <list_iterator object at 0x02BC53F0>
# >>> result = a.__iter__()
# >>> dir(result)
# ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
# >>> result.__next__()
# 1
# >>> result.__next__()
# 2
# >>> result.__next__()
# 3
# >>> result.__next__()
# Traceback (most recent call last):
#   File "<pyshell#10>", line 1, in <module>
#     result.__next__()
# StopIteration

#迭代器一定是一个可迭代对象
# >>> isinstance(a, Iterator)
# False
# >>> isinstance(a, Iterable)
# True
# >>> isinstance(result, Iterable)
# True
# >>> isinstance(result, Iterator)
# True

# >>> a = [3,4,5]
# >>> next(a)
# Traceback (most recent call last):
#   File "<pyshell#1>", line 1, in <module>
#     next(a)
# TypeError: 'list' object is not an iterator
# >>> result = iter(a)
# >>> next(result)
# 3
# >>> next(result)
# 4
# >>>

#迭代器是一个懒加载模式，用的时候才生成

##############
# class SC:
#     def __iter__(self):
#         return self
#     def __next__(self):
#         pass

###################生成器#############
#特殊的迭代器
#就是为了写迭代器更加的优雅

#1、使用生成器表达式
# >>> result = iter(a)
# >>> next(result)
# 3
# >>> next(result)
# 4
# >>> a
# [3, 4, 5]
# >>> g1 = ( x for x in a)
# >>> type(g1)
# <class 'generator'>
# >>> dir(g1)
# ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']

#2、yield关键 -->生成器函数
#yield关键字：保留中间算法，下次继续执行
#当调用next值时，遇到yield就是暂停运行，并且返回yield后面的值
#当再次调用next时，会从刚才暂停的地方继续运行，直到运行下一个yield

# def get_content():
#     print("start yield....")
#     yield 3
#     print("second yield...")
#     yield 4
#     print("third yield...")
#     yield 5
#     print("end.....")
#
# a = get_content()
# # print(dir(a))
# print("*"*20)
# print(next(a))
# print(next(a))
# print("*"*20)
# result = next(a)
# print(result)
# print(next(a))

# def get_func():
#     i = 0
#     while True:
#         i +=1
#         yield i
# a = get_func()
# print(next(a))
# print(next(a))

#使用生成器实现斐波拉契数列
#1，1，2，3，5，8，13，21

########send
# def counter():
#     count = 1
#     while True:
#         val = yield count
#         print(f'val is {val}')
#         if val is not None:
#             print(f'val is {val}')
#             count = val
#         else:
#             count +=1
#
# count = counter()
# print(next(count))
# # print(next(count))
# count.send(10)  #返回一个新的值给yield count
# print(next(count))

#手动关闭当前生成器，关闭之后不能再继续生成值
# count.close()
# print(next(count))


#yield  与field from
# def f1():
#     yield range(10)
#
# def f2():
#     yield from range(10)
#     #for item in range(10):
#     #   yield item
# it1 = f1()
# it2 = f2()
# print(it1)
# print(it2)
# for i in it1:
#     print(i)
# print("*"*20)
# for i in it2:
#     print(i)

